iT邦幫忙

2021 iThome 鐵人賽

DAY 18
0
Modern Web

成為Canvas Ninja ! ~ 理解2D渲染的精髓系列 第 18

Day18 - 物理模擬篇 - 彈力、引力與磁力III - 成為Canvas Ninja ~ 理解2D渲染的精髓

  • 分享至 

  • xImage
  •  

二維彈性模擬(第二部分)

我們在上一篇文做完了整體案例場景的搭建,而我們接下來則是要把後續的物理運算做完~

簡單用圖片講解一下這個案例的物理模型 :

img

畫面中每一顆球都是以具有彈力Cord(弦) 來串連,而球本身會具有重量,
這意味著整條彈力鍊在靜止的時候,重力彈力 其實會維持打平的狀態。

而若今天我們用某種手段去改變之間的距離,這樣就會破壞彈力重力之間的平衡。

弦(Cord)拉長的時候,兩顆球之間的彈力就會變強,進而導致上面的球被往拉,下面被往拉,而上面又連鎖影響更上面的

實錄影片:
Yes

怎麼實作抓取球的部分?

這部分的話可以利用泡沫排序法(Bubble Sorting);

邏輯流程上大概是像這樣的:

  • 監聽滑鼠點擊到Canvas, 抓取clientX/clientY
  • 用for loop 一一比對滑鼠點擊點和每一顆球的距離
  • 距離最小者(並且同時要小於最大容許抓取距離)就是被抓取到的那顆球
grabBall(x, y) {
    if (!!this.ballGrabbed) return;
    // 用泡沫排序法去求得目前距離滑鼠位置最近的球
    this.ballGrabbed = this.balls[0];
    let shortestDist = this.getDist(x, y, this.ballGrabbed);
    for (const ball of this.balls) {
      const dist = this.getDist(x, y, ball);
      if (dist <= shortestDist) {
        shortestDist = dist;
        this.ballGrabbed = ball;
      }
    }
    if (this.ballGrabbed.fixed || shortestDist > MAX_GRAB_DIST) return;
    this.pullBall(x, y, shortestDist)
  }

其餘邏輯的部分其實跟一維彈力模擬差異不大

完整程式的部分可以看這邊的Repo~

https://github.com/mizok/ithelp2021/tree/master/src/js/elastic-2d/index.js

Repo 的 github page :
https://mizok.github.io/ithelp2021/elastic-2d.html

如果對過程中的運算有問題,都可以在下面的留言區提出~ 我會盡可能地去回答

在接下來的文章,我們將會提到磁力/ 引力 的實作,磁力/ 引力其實和彈力有異曲同工之妙, 敬請各位期待 :D ~


上一篇
Day17 - 物理模擬篇 - 彈力、引力與磁力II - 成為Canvas Ninja ~ 理解2D渲染的精髓
下一篇
Day19 - 中場休息時間 - 怎麼樣用Canvas精準的寫出一個『字』 - 成為Canvas Ninja ~ 理解2D渲染的精髓
系列文
成為Canvas Ninja ! ~ 理解2D渲染的精髓31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言